package org.jeecg.modules.nikeProject.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.desensitization.enums.SensitiveEnum;
import org.jeecg.common.desensitization.util.SensitiveInfoUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.nikeProject.entity.SportsProject;
import org.jeecg.modules.nikeProject.entity.SportsProjectReview;
import org.jeecg.modules.nikeProject.entity.SportsScoreRule;
import org.jeecg.modules.nikeProject.entity.vo.RuleVO;
import org.jeecg.modules.nikeProject.entity.vo.UpdateReviewVO;
import org.jeecg.modules.nikeProject.entity.vo.QueryProjectReviewVO;
import org.jeecg.modules.nikeProject.mapper.SportsProjectMapper;
import org.jeecg.modules.nikeProject.mapper.SportsProjectReviewMapper;
import org.jeecg.modules.nikeProject.mapper.SportsScoreRuleMapper;
import org.jeecg.modules.nikeProject.service.ISportsProjectReviewService;
import org.jeecg.modules.nikeProject.service.ISportsProjectService;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description: 案例评审表
 * @Author: jeecg-boot
 * @Date:   2024-12-20
 * @Version: V1.0
 */
@Service
@Slf4j
public class SportsProjectReviewServiceImpl extends ServiceImpl<SportsProjectReviewMapper, SportsProjectReview> implements ISportsProjectReviewService{
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SportsProjectReviewMapper sportsProjectReviewMapper;
    @Autowired
    private SportsScoreRuleMapper sportsScoreRuleMapper;
    @Autowired
    private ISportsProjectService sportsProjectService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private SportsProjectMapper sportsProjectMapper;

    @Override
    public Result<?> getJudgeReviewList(Page<SportsProjectReview> page, QueryProjectReviewVO reviewVO) {
        String projectName = "";
        String userId = "";
        JSONObject object = new JSONObject();
        SysUser sysUser = sysUserMapper.getUserByName(reviewVO.getUsername());
        userId = sysUser.getId();
        //查询当前用户下对应的所有案例列表
        LambdaQueryWrapper<SportsProjectReview> queryWrapper = getReviewQuery(reviewVO, userId);
        IPage<SportsProjectReview> iPage = sportsProjectReviewMapper.selectPage(page, queryWrapper);
        List<SportsProjectReview> list = iPage.getRecords();
        //循环获取视频快照图片
        if (null != list && list.size() > 0) {
            list.forEach(x -> {
                SportsProject sportsProject = sportsProjectMapper.selectById(x.getProjectId());
                String caseName = sportsProjectService.getDSTData(x.getCaseName(), x.getReviewer(), x.getSchoolName(), sportsProject.getCreateBy(), "spec");
                if (caseName.contains("年推广大使申报书")){
                    x.setCaseName(caseName + "(" + x.getProjectId() + ")");
                } else {
                    x.setCaseName(caseName);
                }
                if (null != x.getCaseType() && !"".equals(x.getCaseType())) {
                    x.setCaseTypeName(getCaseTypeName(x.getCaseType()));
                }
                x.setSnapshotUrl(sportsProjectService.getSnapShotUrl(x.getProjectId()));
                x.setReviewer(SensitiveInfoUtil.getEncodeData(SensitiveInfoUtil.getDecodeData(x.getReviewer()), SensitiveEnum.CHINESE_NAME));
            });
        }

        //全部数量
        int allTotal = this.getProjectViewTotal(projectName, userId, null, reviewVO.getReviewType());
        object.put("allTotal", allTotal);
        //未评分数量
        reviewVO.setReviewStatus(CommonConstant.PROJECT_REVIEW_STATUS_PENDING);
        queryWrapper = getReviewQuery(reviewVO, userId);
        int pendingTotal =  sportsProjectReviewMapper.selectList(queryWrapper).size();
        object.put("pendingTotal", pendingTotal);
        //已评分未提交数量（一审，二审）
        reviewVO.setReviewStatus(CommonConstant.PROJECT_REVIEW_STATUS_SCORE);
        queryWrapper = getReviewQuery(reviewVO, userId);
        int unSubmitTotal = sportsProjectReviewMapper.selectList(queryWrapper).size();
        object.put("unSubmitTotal", unSubmitTotal);
        //已提交案例数量
        reviewVO.setReviewStatus(CommonConstant.PROJECT_REVIEW_STATUS_FINISH);
        queryWrapper = getReviewQuery(reviewVO, userId);
        int finishTotal = sportsProjectReviewMapper.selectList(queryWrapper).size();
        object.put("finishTotal", finishTotal);
        //二审已提交数量
        reviewVO.setReviewStatus(CommonConstant.PROJECT_REVIEW_STATUS_SENIOR_SUBMIT);
        queryWrapper = getReviewQuery(reviewVO, userId);
        int seniorSubmitTotal = sportsProjectReviewMapper.selectList(queryWrapper).size();
        object.put("seniorSubmitTotal", seniorSubmitTotal);
        //补充材料已保存数量
        reviewVO.setReviewStatus(CommonConstant.PROJECT_REVIEW_STATUS_PENDING_IT);
        queryWrapper = getReviewQuery(reviewVO, userId);
        int unSubmitItTotal = sportsProjectReviewMapper.selectList(queryWrapper).size();
        object.put("unSubmitItTotal", unSubmitItTotal);

        object.put("list", list);
        object.put("pageNo", page.getCurrent());
        object.put("pageSize", page.getSize());
        return Result.OK("success", object);
    }

    /**
     * 拼查询语句
     * @param reviewVO
     * @param userId
     * @return
     */
    public LambdaQueryWrapper<SportsProjectReview> getReviewQuery(QueryProjectReviewVO reviewVO, String userId){
        LambdaQueryWrapper<SportsProjectReview> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SportsProjectReview::getJudgeUserId, userId);
        queryWrapper.eq(SportsProjectReview::getIzActive, CommonConstant.COMMON_STATUS_N);
        if (!"".equals(reviewVO.getProjectName()) && null != reviewVO.getProjectName()) {
            queryWrapper.like(SportsProjectReview::getCaseName, reviewVO.getProjectName());
        }
        if (null != reviewVO.getReviewStatus() && !"".equals(reviewVO.getReviewStatus())) {
            //reviewStatus=2  一二审已打分（包括争议） reviewStatus=3  已提交
            if (reviewVO.getReviewStatus().equals(CommonConstant.PROJECT_REVIEW_STATUS_SCORE) || reviewVO.getReviewStatus().equals(CommonConstant.PROJECT_REVIEW_STATUS_FINISH)){
                queryWrapper.eq(SportsProjectReview::getReviewStatus, reviewVO.getReviewStatus());
                queryWrapper.ne(SportsProjectReview::getReviewType, CommonConstant.REVIEW_TYPE_INTERNATIONAL_TRAVEL);
            }
            //reviewStatus=5  二审已提交（包括争议）
            else if (reviewVO.getReviewStatus().equals(CommonConstant.PROJECT_REVIEW_STATUS_SENIOR_SUBMIT)){
                queryWrapper.eq(SportsProjectReview::getReviewStatus, CommonConstant.PROJECT_REVIEW_STATUS_PENDING_IT);
                List<String> list = new ArrayList<>();
                list.add(CommonConstant.REVIEW_TYPE_SENIOR);
                list.add(CommonConstant.REVIEW_DISPUTE_FINAL);
                queryWrapper.in(SportsProjectReview::getReviewType, list);
            }
            //reviewStatus=4  已保存补充材料
            else if (reviewVO.getReviewStatus().equals(CommonConstant.PROJECT_REVIEW_STATUS_PENDING_IT)){
                queryWrapper.eq(SportsProjectReview::getReviewStatus, CommonConstant.PROJECT_REVIEW_STATUS_SCORE);
                queryWrapper.eq(SportsProjectReview::getReviewType, CommonConstant.REVIEW_TYPE_INTERNATIONAL_TRAVEL);
            }
            //reviewStatus=1 未打分
            else {
                queryWrapper.eq(SportsProjectReview::getReviewStatus, reviewVO.getReviewStatus());
                queryWrapper.ne(SportsProjectReview::getReviewType, CommonConstant.REVIEW_TYPE_INTERNATIONAL_TRAVEL);
            }
        }
        return queryWrapper;
    }

    /**
     * 转换案例类型
     * @param caseType
     * @return
     */
    public String getCaseTypeName(String caseType){
        String caseTypeName;
        switch (caseType) {
            case CommonConstant.CASE_TYPE_TEACH:
                caseTypeName = CommonConstant.CASE_TYPE_TEACH_NAME;
                break;
            case CommonConstant.CASE_TYPE_CULTURE:
                caseTypeName = CommonConstant.CASE_TYPE_CULTURE_NAME;
                break;
            case CommonConstant.CASE_TYPE_ACTIVITY:
                caseTypeName = CommonConstant.CASE_TYPE_ACTIVITY_NAME;
                break;
            case CommonConstant.CASE_TYPE_OTHER:
                caseTypeName = CommonConstant.CASE_TYPE_OTHER_NAME;
                break;
            default:
                caseTypeName = "";
        }
        return caseTypeName;
    }

    public int getProjectViewTotal(String projectName, String userId, String reviewStatus, String judgeType){
        return sportsProjectReviewMapper.getCount(userId, projectName, reviewStatus, judgeType);
    }

    /**
     * 提交打分,将状态改为已提交
     * @param ids
     * @param username
     */
    @Override
    @Transactional
    public Result<?> submitProjectReview(List<String> ids, String username) {
        //获取评审打分案例列表
        List<SportsProjectReview> list = getSportsProjectReviewListByIds(ids);
        if (null != list && list.size() > 0){
            list.forEach(x ->{
                if (x.getReviewStatus().equals(CommonConstant.PROJECT_REVIEW_STATUS_PENDING_IT)){
                    updateInternatioanlTravelReview(x, username);
                } else{
                    x.setUpdateTime(new Date());
                    x.setUpdateBy(username);
                    x.setLevelType(getLevelType(x.getScore()));
                     //如果当前评审提交的数据为二审
                    if(x.getReviewType().equals(CommonConstant.REVIEW_TYPE_SENIOR) && (x.getRoleType().equals(CommonConstant.ROLE_TYPE_TE) || x.getRoleType().equals(CommonConstant.ROLE_TYPE_SM)) ) {
                        //并且角色校长和体育老师才需要国际行
                        x.setReviewStatus(CommonConstant.PROJECT_REVIEW_STATUS_PENDING_IT);
                    } else {
                        x.setReviewStatus(CommonConstant.PROJECT_REVIEW_STATUS_FINISH);
                    }
                    sportsProjectReviewMapper.updateById(x);
                    //如果是争议案例，可直接将案例平均分设置为初审争议评分/复审争议评分
                    SportsProject sportsProject = sportsProjectMapper.selectById(x.getProjectId());
                    if (CommonConstant.REVIEW_DISPUTE_FIRST.equals(x.getReviewType()) || CommonConstant.REVIEW_DISPUTE_FINAL.equals(x.getReviewType())) {
                        BigDecimal score = x.getScore();
                        if (CommonConstant.REVIEW_DISPUTE_FIRST.equals(x.getReviewType())) {
                            sportsProject.setFirstDisputeScore(score);
                            sportsProject.setAverageOrdinary(score);
                            sportsProject.setProjectStatus(CommonConstant.PROJECT_STATUS_FINISH_ORDINARY);
                        } else {
                            sportsProject.setAverageSenior(score);
                            sportsProject.setFinalDisputeScore(score);
                            sportsProject.setProjectStatus(CommonConstant.PROJECT_STATUS_FINISH_SENIOR);
                        }
                        sportsProject.setUpdateBy(username);
                        sportsProject.setUpdateTime(new Date());
                        sportsProjectMapper.updateById(sportsProject);
                    }
                }

                //查询当前案例的角色是否为校长，教研员，推荐大使。如果是则直接一轮打分即可
                /*if (CommonConstant.COMMON_STATUS_Y.equals(sportsProject.getIzDispute()) && !CommonConstant.ROLE_TYPE_TE.equals(sportsProject.getRoleType())){
                    sportsProject.setProjectStatus(CommonConstant.PROJECT_STATUS_FINISH_SENIOR);
                    sportsProject.setUpdateBy(username);
                    sportsProject.setUpdateTime(new Date());
                    sportsProjectMapper.updateById(sportsProject);
                }*/
            });
        }
        return Result.OK("提交成功！");
    }

    /**
     * 评分等级标准：
     * 1-极好（91-100分），2-好（81-90分），3-中等（71-80分），4-一般（60-70分）， 5-不足（0-59分）
     * @param score 当前得分
     * @return
     */
    public static Integer getLevelType(BigDecimal score) {
        if (isBetween(score, new BigDecimal(91.00), new BigDecimal(100.00))) {
            return 1;
        } else if (isBetween(score, new BigDecimal(81.00), new BigDecimal(90.99))) {
            return 2;
        } else if (isBetween(score, new BigDecimal(71.00), new BigDecimal(80.99))) {
            return 3;
        } else if (isBetween(score, new BigDecimal(60.00), new BigDecimal(70.99))) {
            return 4;
        } else {
            // 0- 59分则返回5
            return 5;
        }
    }

    /**
     * @param value 当前分
     * @param minValue  最小分值
     * @param maxValue  最大分值
     * @return
     */
    public static boolean isBetween(BigDecimal value, BigDecimal minValue, BigDecimal maxValue) {
        // 首先确保value不小于minValue
        int compareToMin = value.compareTo(minValue);
        // 然后确保value不大于maxValue
        int compareToMax = value.compareTo(maxValue);

        // 如果value大于等于minValue且小于等于maxValue，则返回true
        return compareToMin >= 0 && compareToMax <= 0;
    }

    /**
     * 更新打分信息   状态改为已打分
     * @param updateReviewVO
     * @param username
     * @return
     */
    @Override
    public Result<?> updateProjectReview(UpdateReviewVO updateReviewVO, String username) {
        if (null == updateReviewVO.getList() && updateReviewVO.getList().size() < 0){
            return Result.ok("无数据需要更新");
        }

        if ("".equals(updateReviewVO.getComments()) || null == updateReviewVO.getComments()){
            return Result.ok("请为案例填写评语！");
        }

        SportsProjectReview sportsProjectReview = getSportsReviewById(updateReviewVO.getReviewId());
        sportsProjectReview.setUpdateBy(username);
        sportsProjectReview.setUpdateTime(new Date());
        sportsProjectReview.setComments(updateReviewVO.getComments());
        sportsProjectReview.setReviewStatus(CommonConstant.PROJECT_REVIEW_STATUS_SCORE);
        if (null != sportsProjectReview.getLevelType() && sportsProjectReview.getLevelType() > 0) {
            sportsProjectReview.setLevelType(0);
        }
        String scoreDetail = JSON.toJSONString(updateReviewVO.getList());
        sportsProjectReview.setScoreDetail(scoreDetail);
        sportsProjectReview.setScore(getTotalScore(updateReviewVO.getList()));
        int i = sportsProjectReviewMapper.updateById(sportsProjectReview);
        if (i > 0){
            //如果成功，则将数据返回给到前端
            return Result.OK("评分成功！", sportsProjectReview);
        }
        return Result.error("评分失败！");
    }

    @Override
    public Result<?> saveInternationalTravelReview(UpdateReviewVO updateReviewVO, String username) {
        SportsProjectReview sportsProjectReview = getSportsReviewById(updateReviewVO.getReviewId());
        SportsProjectReview itReview = getSportsITReview(sportsProjectReview.getProjectId(), sportsProjectReview.getJudgeUserId(), CommonConstant.REVIEW_TYPE_INTERNATIONAL_TRAVEL);

        //判断当前评审下的二审评分数据是否有提交，如果未提交不能进行国际行的评分
//        SportsProjectReview userFinalReview = getUserFinalReview(itReview.getJudgeUserId(), itReview.getProjectId(), CommonConstant.REVIEW_TYPE_SENIOR);
        if (!CommonConstant.PROJECT_REVIEW_STATUS_PENDING_IT.equals(sportsProjectReview.getReviewStatus())){
            return Result.error("当前评审案例评分未提交，不能进行打分操作！");
        }
        itReview.setUpdateTime(new Date());
        itReview.setComments(updateReviewVO.getComments());
        itReview.setReviewStatus(CommonConstant.PROJECT_REVIEW_STATUS_SCORE);
        String scoreDetail = JSON.toJSONString(updateReviewVO.getList());
        itReview.setInternationalTravelSummary(updateReviewVO.getInternationTravelSummary());
        itReview.setScoreDetail(scoreDetail);
        int i = sportsProjectReviewMapper.updateById(itReview);
        if (i > 0){
            //当保存时，将对应的二审案例状态改成6
            sportsProjectReview.setReviewStatus(CommonConstant.REVIEW_STATUS_SAVE_IT);
            sportsProjectReview.setUpdateTime(new Date());
            sportsProjectReviewMapper.updateById(sportsProjectReview);

            //如果成功，则将数据返回给到前端
            return Result.OK("评分成功！");
        }
        return Result.error("评分失败！");
    }

    public SportsProjectReview getReviewSeniorByUserId(String projectId, String userId){
        LambdaQueryWrapper<SportsProjectReview> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SportsProjectReview::getProjectId, projectId);
        queryWrapper.eq(SportsProjectReview::getJudgeUserId, userId);
        queryWrapper.eq(SportsProjectReview::getIzActive, CommonConstant.COMMON_STATUS_N);
        queryWrapper.eq(SportsProjectReview::getReviewStatus, CommonConstant.PROJECT_REVIEW_STATUS_PENDING_IT);
        return sportsProjectReviewMapper.selectOne(queryWrapper);
    }

    public void updateInternatioanlTravelReview(SportsProjectReview sportsProjectReview, String username){
        //国际行数据
        SportsProjectReview itReview = getSportsITReview(sportsProjectReview.getProjectId(), sportsProjectReview.getJudgeUserId(), CommonConstant.REVIEW_TYPE_INTERNATIONAL_TRAVEL);
        itReview.setReviewStatus(CommonConstant.PROJECT_REVIEW_STATUS_FINISH);
        itReview.setUpdateTime(new Date());
        itReview.setUpdateBy(username);
        sportsProjectReviewMapper.updateById(itReview);

        //        SportsProjectReview seniorProjectReview = getReviewSeniorByUserId(sportsProjectReview.getProjectId(), sportsProjectReview.getJudgeUserId());
        sportsProjectReview.setReviewStatus(CommonConstant.PROJECT_REVIEW_STATUS_FINISH);
        sportsProjectReview.setUpdateBy(username);
        sportsProjectReview.setUpdateTime(new Date());
        sportsProjectReviewMapper.updateProjectReview(sportsProjectReview);
    }

    @Override
    public Result<?> submitInternationalTravelReview(List<String> ids, String username) {
        //查询出当用户对应的二审评审案例
        List<SportsProjectReview> list = getSportsProjectReviewListByIds(ids);
        if (null != list && list.size() > 0){
            list.forEach(x -> {
                //国际行数据
                SportsProjectReview seniorProjectReview = getSportsITReview(x.getProjectId(), x.getJudgeUserId(), CommonConstant.REVIEW_TYPE_SENIOR);
                seniorProjectReview.setReviewStatus(CommonConstant.PROJECT_REVIEW_STATUS_FINISH);
                seniorProjectReview.setUpdateTime(new Date());
                seniorProjectReview.setUpdateBy(username);
                sportsProjectReviewMapper.updateById(seniorProjectReview);

                //        SportsProjectReview seniorProjectReview = getReviewSeniorByUserId(sportsProjectReview.getProjectId(), sportsProjectReview.getJudgeUserId());
                x.setReviewStatus(CommonConstant.PROJECT_REVIEW_STATUS_FINISH);
                x.setUpdateBy(username);
                x.setUpdateTime(new Date());
                sportsProjectReviewMapper.updateProjectReview(x);
            });
        }
        return Result.OK("国际行评分提交成功！");
    }

    public SportsProjectReview getUserFinalReview(String judgeUserId, String projectId, String reviewType){
        LambdaQueryWrapper<SportsProjectReview> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(SportsProjectReview::getProjectId, projectId);
        lambdaQueryWrapper.eq(SportsProjectReview::getReviewType, reviewType);
        lambdaQueryWrapper.eq(SportsProjectReview::getJudgeUserId, judgeUserId);
        lambdaQueryWrapper.eq(SportsProjectReview::getIzActive, CommonConstant.COMMON_STATUS_N);
        return sportsProjectReviewMapper.selectOne(lambdaQueryWrapper);
    }

    public BigDecimal getTotalScore(List<RuleVO> list) {
        BigDecimal totalScore = BigDecimal.ZERO;
        for(int i = 0; i < list.size(); i ++){
            RuleVO ruleVO = list.get(i);
            SportsScoreRule sportsScoreRule = getScoreRuleById(ruleVO.getRuleId());
            if (null != ruleVO.getScore()) {
                BigDecimal decimalEquivalent = sportsScoreRule.getScoreValue().movePointLeft(2);
                totalScore = totalScore.add(ruleVO.getScore().multiply(decimalEquivalent).setScale(2, BigDecimal.ROUND_HALF_UP));
            }
        }
        return totalScore;
    }

    public SportsScoreRule getScoreRuleById(String ruleId) {
        LambdaQueryWrapper<SportsScoreRule> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsScoreRule::getIzActive, CommonConstant.COMMON_STATUS_N);
        lambdaQueryWrapper.eq(SportsScoreRule::getId, ruleId);
        return sportsScoreRuleMapper.selectOne(lambdaQueryWrapper);
    }


    public SportsProjectReview getSportsReviewById(String reviewId){
        LambdaQueryWrapper<SportsProjectReview> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(SportsProjectReview::getId, reviewId);
        lambdaQueryWrapper.eq(SportsProjectReview::getIzActive, CommonConstant.COMMON_STATUS_N);
        return sportsProjectReviewMapper.selectOne(lambdaQueryWrapper);
    }

    public SportsProjectReview getSportsITReview(String projectId, String judgeUserId, String reviewType){
        LambdaQueryWrapper<SportsProjectReview> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SportsProjectReview::getProjectId, projectId);
        lambdaQueryWrapper.eq(SportsProjectReview::getJudgeUserId, judgeUserId);
        lambdaQueryWrapper.eq(SportsProjectReview::getReviewType, reviewType);
        lambdaQueryWrapper.eq(SportsProjectReview::getIzActive, CommonConstant.COMMON_STATUS_N);
        return sportsProjectReviewMapper.selectOne(lambdaQueryWrapper);
    }

    public List<SportsProjectReview> getSportsProjectReviewListByIds(List<String> ids){
        LambdaQueryWrapper<SportsProjectReview> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(SportsProjectReview::getId, ids);
        lambdaQueryWrapper.eq(SportsProjectReview::getIzActive, CommonConstant.COMMON_STATUS_N);
        return sportsProjectReviewMapper.selectList(lambdaQueryWrapper);
    }

}
